#include "pkgframe_project.h"
#include "ui_pkgframe_project.h"
#include <QDebug>
#include <QFileDialog>
#include <QStringList>
#include <QCoreApplication>
#include "config_parse/config_parse.h"
#include <QMessageBox>
//#include <QDialog>

// 拖入控件
#include <QDragEnterEvent>
#include <QMimeData>
#include <QUrl>

pkgframe_project::pkgframe_project(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::pkgframe_project)
{
    ui->setupUi(this);

    package_frame_init(&this->pkgf, NULL, 1);
    keyinit();
    setAcceptDrops(true);
    this->setWindowTitle("pkgframe_tool");


//    connect(ui->pushButton_5, &QPushButton::clicked,this, &pkgframe_project::test1);
//    connect(ui->pushButton_6, SIGNAL(clicked()),this,SLOT(test2()));


    // done
    connect(ui->pushButton_2, SIGNAL(clicked()),this,SLOT(keyManagerOpen()));
    connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(openFiles()));
    connect(ui->readPackageButtom, SIGNAL(clicked()), this, SLOT(readPackageSlot()));
    connect(ui->packageButtom, SIGNAL(clicked()), this, SLOT(packageSlot()));
    connect(ui->outputButtom, SIGNAL(clicked()), this, SLOT(outputPackageSlot()));

//    QString i("1234567890");
//    qDebug() << i.left(3);
//    qDebug() << i.right(3);
}

pkgframe_project::~pkgframe_project()
{
    delete ui;
}

void pkgframe_project::test1()
{
    int row = ui->tableWidget->rowCount();
    qDebug() << row;
    ui->tableWidget->insertRow(row);
    QTableWidgetItem *headerItem = new QTableWidgetItem(QString("%1").arg(row+1));
    ui->tableWidget->setVerticalHeaderItem(row, headerItem);
}

void pkgframe_project::test2()
{
    int row = ui->tableWidget->currentRow();
    qDebug() << "row = " << row;
    tableWeightRemoveRow(row);
}

void pkgframe_project::openFiles()
{
    QStringList filenames=QFileDialog::getOpenFileNames(this,tr("文件选择"));
    qDebug() << filenames;
    QStringList params;
    if (ui->comboBox->currentIndex() >= 0) {
        auto t_key = this->kinfo.at(ui->comboBox->currentIndex());
        params << QString::number(t_key.type) << t_key.publisher;
    }

    for (auto i : filenames) {
        tableWeightAddRow(QStringList(i) << params);
    }

}

void pkgframe_project::keyManagerClose()
{
    qDebug() << "receive close";
    this->show();
    disconnect(this->key_manager, SIGNAL(closed()),this,SLOT(keyManagerClose()));
    delete key_manager;

    for (auto i : kinfo) {
        ui->comboBox->addItem(i.name);
        qDebug() << i.name;
    }

    if (key_change_flag) {
        key_change_flag = false;
        QFile keyconfig("keyconfig.ini");
//        keyconfig.open(QIODevice::WriteOnly | QIODevice::Text);
        struct config_list list;
        config_parse_init(&list);
        for (auto i : kinfo) {
            config_parse_add_topic(&list, i.name.toLatin1().data());
            config_parse_add_line(&list, "publisher", i.publisher.toLatin1().data());
            config_parse_add_line(&list, "key", i.key.toBase64().data());
            config_parse_add_line(&list, "type", QByteArray::number(i.type).data());
            config_parse_add_empty(&list);
        }
        config_parse_create_file(&list, "keyconfig.ini");
        config_parse_free(&list);
    }
}

void pkgframe_project::keyManagerOpen()
{
    ui->comboBox->clear();
    key_manager = new key(kinfo);
//    key_manager->setWindowModality(Qt::ApplicationModal);
    key_manager->setWindowModality(Qt::WindowModal);
    key_manager->show();
    connect(this->key_manager, SIGNAL(closed()),this,SLOT(keyManagerClose()));
    connect(this->key_manager, SIGNAL(keyChange()),this,SLOT(keyManagerChange()));

    this->hide();
}

void pkgframe_project::keyManagerChange()
{
    key_change_flag = true;
}

void pkgframe_project::readPackageSlot()
{
    int row;
    if (ui->tableWidget->rowCount() == 1) {
        row =0;
    } else if (ui->tableWidget->currentRow() != -1) {
        row = ui->tableWidget->currentRow();
    } else {
        QMessageBox::information(this, "tips", "please selete row and retry");
        return;
    }
    qDebug() << "row = " << row;
    qDebug() << "name = " << ui->tableWidget->item(row, 0)->text();
    if (ui->comboBox->currentIndex() == -1) {
        QMessageBox::information(this, "tips", "please add key first");
        return;
    }

    keyinfo tkey("","",0,"");
    for (auto i : this->kinfo) {
        if (i.name == ui->comboBox->currentText()) {
            tkey = i;
            qDebug() << "key: " <<tkey.key;
            break;
        }
    }
    if (tkey.name.isEmpty()) {
        QMessageBox::critical(this, "error", "system error in find key");
        return;
    }

    package_frame_free(&pkgf);
//    auto key_qba = QByteArray::fromBase64( tkey.key);
//    qDebug() << "tkey.key = " << tkey.key;
//    qDebug() << "tkey.key len = " << tkey.key.size();
    if (tkey.key.size() == 32) {
        package_frame_init(&pkgf, tkey.key.data(), 1);
    } else if (tkey.key.size() == 0) {
        package_frame_init(&pkgf, NULL, 1);
    } else {
        QMessageBox::information(this, "tips", "the key is broken");
        return;
    }

    auto ret = package_frame_read_package(&pkgf, ui->tableWidget->item(row, 0)->text().toLatin1().data());
    qDebug() << "ret = " << ret;
    if (ret == 0) {
        QMessageBox::information(this, "result", "read 0 file");
//        package_frame_free(&pkgf);
        return;
    } else if (ret < 0) {
        QMessageBox::critical(this, "error", QString("read package fail with code %1").arg(ret));
        return;
    }

    tableWeightRemoveRow(-1);
    auto unit = pkgf.unit;
    while (unit) {
        QStringList l;
        l << unit->filename << QString::number(unit->type) << unit->publisher << unit->version << unit->note;
        tableWeightAddRow(l);
        unit = unit->next;
    }
}

void pkgframe_project::outputPackageSlot()
{
    auto lines = getTableWeightSelectRows();
    if (lines.isEmpty()) {
        QMessageBox::information(this, "warning", "please select files");
        return;
    }

    // 第二个参数是对话框标题，第三个参数是初始目录
    QString selectedDirectory = QFileDialog::getExistingDirectory(this, "选择文件夹");
    if (selectedDirectory.isEmpty()) {
        return;
    }

    int ret,cnt=0;
    for (auto i : lines) {
        ret = package_frame_output_file(&this->pkgf, ui->tableWidget->item(i, 0)->text().toLatin1().data(), selectedDirectory.toLatin1().data());
        if (ret) {
            QMessageBox::warning(this, "生成异常", ui->tableWidget->item(i, 0)->text() + " 生成失败");
            return;
        }
        cnt++;
    }

    QMessageBox::information(this, "result", "成功生成" + QString::number(cnt) + "个文件");
}

void pkgframe_project::packageSlot()
{
    auto lines = getTableWeightSelectRows();
    if (lines.isEmpty()) {
        QMessageBox::information(this, "warning", "please select files");
        return;
    }

    QString fileName = QFileDialog::getSaveFileName(this,
        tr("Save File"), "", tr("package files (*.pk);;custom (*.*)"));
    if (fileName.isEmpty()) return;
    qDebug() << fileName;

    int ret;

    keyinfo tkey("","",0,"");
    for (auto i : this->kinfo) {
        if (i.name == ui->comboBox->currentText()) {
            tkey = i;
            qDebug() << "key: " <<tkey.key;
            break;
        }
    }
    if (tkey.name.isEmpty()) {
        QMessageBox::critical(this, "error", "system error in find key");
        return;
    }

    package_frame_free(&this->pkgf);
    if (tkey.key.size() == 32) {
        package_frame_init(&pkgf, tkey.key.data(), 1);
    } else if (tkey.key.size() == 0) {
        package_frame_init(&pkgf, NULL, 1);
    } else {
        QMessageBox::information(this, "tips", "the key is broken");
        return;
    }
    for (auto i : lines) {
        char *t_name="", *t_publisher="", *t_note="", *t_version="", t_type=0;
        if (ui->tableWidget->item(i, 0)) t_name = ui->tableWidget->item(i, 0)->text().toLatin1().data();
        if (ui->tableWidget->item(i, 1)) t_type = ui->tableWidget->item(i, 1)->text().toInt();
        if (ui->tableWidget->item(i, 2)) t_publisher = ui->tableWidget->item(i, 2)->text().toLatin1().data();
        if (ui->tableWidget->item(i, 3)) t_version = ui->tableWidget->item(i, 3)->text().toLatin1().data();
        if (ui->tableWidget->item(i, 4)) t_note = ui->tableWidget->item(i, 4)->text().toLatin1().data();
        ret = package_frame_append(&this->pkgf, t_name,t_publisher, t_note, t_version, t_type);
        if (ret) {
            QMessageBox::critical(this, "error", "file " + ui->tableWidget->item(i, 0)->text() + " append fail " + QString::number(ret));
            return;
        }
    }
    ret = package_frame_generate(&this->pkgf, fileName.toLatin1().data());
    if (ret >= 0) {
        QMessageBox::information(this, "message", QString("成功打包%1个文件 --> %2").arg(ret).arg(fileName));
    } else {
        QMessageBox::critical(this, "error", QString("生成失败 %1").arg(ret));
    }

}

void pkgframe_project::keyinit()
{
    key_change_flag = false;
    QFile keyconfig("keyconfig.ini");
    if (!keyconfig.exists()) {
        keyconfig.open(QIODevice::WriteOnly | QIODevice::Text);
        keyconfig.close();
        qDebug() << "create config";
    } else {
        keyconfig.open(QIODevice::ReadOnly | QIODevice::Text);
        auto text = keyconfig.readAll();
        struct config_list list;
        config_parse_init(&list);
        config_parse_buffer(&list, text.data());

        QStringList sl;
        struct config_list *cur = &list;
        int num=1;
        do {
            cur = config_parse_get_topic(&list, num);
            if (cur) sl.append(cur->value);
            num++;
        } while (cur);
        qDebug() << sl;
        this->kinfo.clear();
        ui->comboBox->clear();

        for (auto i : sl) {
            QString pub = config_parse_get_value_by_key(&list, "publisher", i.toLatin1().data());
            int type = atoi(config_parse_get_value_by_key(&list, "type", i.toLatin1().data()));
            QByteArray key = QByteArray::fromBase64(config_parse_get_value_by_key(&list, "key", i.toLatin1().data()));
            this->kinfo.append(keyinfo(i, pub, type, key));
            ui->comboBox->addItem(i);
        }
        config_parse_free(&list);
    }
}

int pkgframe_project::tableWeightAddRow(QStringList data)
{
    int row = ui->tableWidget->rowCount();
//    qDebug() << row;
    ui->tableWidget->insertRow(row);
    QTableWidgetItem *headerItem = new QTableWidgetItem(QString("%1").arg(row+1));
    ui->tableWidget->setVerticalHeaderItem(row, headerItem);


    // 将item添加到表格的指定位置
    if (!data.isEmpty()) {
        auto col = ui->tableWidget->columnCount();
        for (int i=0;i<col && i<data.size();i++) {
            auto item = new QTableWidgetItem(data.at(i));
            if (i==0) {
                item->setFlags(item->flags() & ~Qt::ItemIsEditable);
                item->setTextAlignment(Qt::AlignRight);  // 显示样式
            }

            ui->tableWidget->setItem(row, i, item);
        }
    }
    return 0;
}

int pkgframe_project::tableWeightRemoveRow(int row)
{
    if (row > ui->tableWidget->rowCount()) return -1;
    if (row < 0) {
        while(ui->tableWidget->rowCount()) {
            ui->tableWidget->removeRow(ui->tableWidget->rowCount()-1);
        }
    } else {
        ui->tableWidget->removeRow(row);
    }
}

QList<int> pkgframe_project::getTableWeightSelectRows()
{
    QList<int> row_list;

    // 获取选择模型
    QItemSelectionModel *selectionModel = ui->tableWidget->selectionModel();
    if (!selectionModel) return row_list;

    // 遍历所有选中的行
    QModelIndexList selectedIndexes = selectionModel->selectedRows();
    for (const QModelIndex &index : selectedIndexes) {
        qDebug() << "Selected Row:" << index.row();
        row_list << index.row();
    }
    return row_list;
}

void pkgframe_project::dragEnterEvent(QDragEnterEvent *event)
{
    if (event->mimeData()->hasUrls()) {
        event->acceptProposedAction();
    }
//    qDebug() << "dragEnterEvent";
}

void pkgframe_project::dragMoveEvent(QDragMoveEvent *event)
{
    if (event->mimeData()->hasUrls()) {
        event->acceptProposedAction();
    }
//    qDebug() << "dragMoveEvent";
}

void pkgframe_project::dropEvent(QDropEvent *event)
{
    if (event->mimeData()->hasUrls()) {
        QList<QUrl> urls = event->mimeData()->urls();
        foreach (const QUrl &url, urls) {
            QString filePath = url.toLocalFile();
//            qDebug() << "Dropped file:" << filePath;
            // 处理文件路径，例如加载文件等
            tableWeightAddRow(QStringList(filePath));
        }
        event->acceptProposedAction();
    }
}

